//#include <iostream>
/*
 * Search.h
 *
 *  Created on: Jun 1, 2009
 *      Author: ruslan
 */

#ifndef SEARCH_H_
#define SEARCH_H_

#include <sstream>
#include <pthread.h>

#include "Lib.h"

using namespace std;

class Search {
public:
	Search(int weeks, int groupsInWeek, int playersInGroup, long maxIteration=-1) {
		WEEKS = weeks;
		GROUPS_IN_WEEK = groupsInWeek;
		PLAYERS_IN_GROUP = playersInGroup;
		MAX_ITERATION = maxIteration;
		playersCnt = GROUPS_IN_WEEK*PLAYERS_IN_GROUP;
		currIteration = 0;
		mtrx3Schedule = NULL;
		wasInit = false;
		status = 0;
		mtrx3BestSchedule = NULL;
		bestIteration = -1;
		hotScheduleStop = false;

		if (pthread_mutex_init(&hotScheduleStopMutex, NULL) == -1) {
			perror("mutex_init error");
		}
	}

	virtual ~Search() {
		if (mtrx3Schedule != NULL)
			Lib::deleteMatrix3(mtrx3Schedule, WEEKS, GROUPS_IN_WEEK);

		if (mtrx3BestSchedule != NULL)
			Lib::deleteMatrix3(mtrx3BestSchedule, WEEKS, GROUPS_IN_WEEK);
	}

	int getWeeks() {
		return WEEKS;
	}

	int getGroupsInWeek() {
		return GROUPS_IN_WEEK;
	}

	int getPlayersInGroup() {
		return PLAYERS_IN_GROUP;
	}

	long getMaxIteration() {
		return MAX_ITERATION;
	}

	long getCurrIteration() {
		return currIteration;
	}

	long getBestIteration() {
		if (bestIteration > 0)
			return bestIteration;
		else
			return currIteration;
	}

	int getPlayersCnt() {
		return playersCnt;
	}

	int*** getSchedule() {
		return mtrx3Schedule;
	}

	int*** getBestSchedule() {
		if (mtrx3BestSchedule == NULL)
			return mtrx3Schedule;
		else
			return mtrx3BestSchedule;
	}

	int*** getCopyOfBestSchedule() {
		int*** newCubBestSchedule;
		if (mtrx3BestSchedule == NULL)
			newCubBestSchedule = Lib::makeCopyOfMtrx3(mtrx3Schedule, WEEKS, GROUPS_IN_WEEK, PLAYERS_IN_GROUP);
		else
			newCubBestSchedule = Lib::makeCopyOfMtrx3(mtrx3BestSchedule, WEEKS, GROUPS_IN_WEEK, PLAYERS_IN_GROUP);
		return newCubBestSchedule;
	}

	int getStatus() {
		return status;
	}

public:
	void stopScheduleGeneration() {
		pthread_mutex_lock( &hotScheduleStopMutex );
		hotScheduleStop = true;
		pthread_mutex_unlock( &hotScheduleStopMutex );
	}

	virtual string getParametersAsString() {
		std::stringstream out;
		out<<"WEEKS = "<<WEEKS <<endl;
		out<<"GROUPS_IN_WEEK = "<<GROUPS_IN_WEEK <<endl;
		out<<"PLAYERS_IN_GROUP = "<<PLAYERS_IN_GROUP <<endl;
		out<<"MAX_ITERATION = "<<MAX_ITERATION<<endl;
		return out.str();
	}

	virtual void init() = 0;
	virtual int ScheduleIt() = 0; // 0 - decision is found; -1 - decision is not found; -2 - iteration error

protected:
	int WEEKS;
	int GROUPS_IN_WEEK;
	int PLAYERS_IN_GROUP;
	long MAX_ITERATION;

	int playersCnt;
	long currIteration;
	int*** mtrx3Schedule; // Schedule
	bool wasInit;
	int status;
	bool hotScheduleStop;
	int*** mtrx3BestSchedule;
	int bestIteration;

private:
	pthread_mutex_t hotScheduleStopMutex;

};

#endif /* SEARCH_H_ */
